package com.lanyou.esb.web;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.lanyou.cook.common.Constants;
import com.lanyou.esb.entity.ClusterNode;
import com.lanyou.esb.repository.ClusterNodeRepository;

@RestController
@RequestMapping(Constants.BASE_URL_API + "/clusterNodes")
public class ClusterNodeController{
	
	@Autowired
	private ClusterNodeRepository clusterNodeRepository;
	
	private Map<String, ClusterNode> nodeMap = new HashMap<>();	//设置缓存
	
	/**
	 * 保存操作前检查是否可以保存,确保节点名称和IP地址唯一
	 * @param name	节点名称
	 * @param ipaddr	IP地址
	 * @param originalId	原始节点ID
	 * @return
	 */
	@RequestMapping(value = "/search/checkIsCanSave", produces = "application/json")
	public String checkIsCanSave(String name, String ipaddr, String originalId) {
		ClusterNode clusterNodeOne = clusterNodeRepository.findByName(name);
		ClusterNode clusterNodeTwo = clusterNodeRepository.findByIpaddr(ipaddr);
		
		if (clusterNodeOne != null) {	//one
			if (clusterNodeTwo != null){	//two
				if (!StringUtils.equals(clusterNodeOne.getId(), clusterNodeTwo.getId())){	//one.id != two.id
					JsonObject result = new JsonObject();
					result.addProperty("isCanSave", false);
					result.addProperty("errorCode", "DUPLICATE");
					return result.toString();	
				}else if (!StringUtils.equals(clusterNodeTwo.getId(), originalId)) {	//one.id == two.id  two.id != id
					JsonObject result = new JsonObject();
					result.addProperty("isCanSave", false);
					result.addProperty("errorCode", "DUPLICATE");
					return result.toString();
				}
			}else if (!StringUtils.equals(clusterNodeOne.getId(), originalId)){ 	//one.id != id
				JsonObject result = new JsonObject();
				result.addProperty("isCanSave", false);
				result.addProperty("errorCode", "DUPLICATE");
				return result.toString();				
			}
		}else if(clusterNodeTwo != null){	//two
			if (!StringUtils.equals(clusterNodeTwo.getId(), originalId)) {	//two.id != id
				JsonObject result = new JsonObject();
				result.addProperty("isCanSave", false);
				result.addProperty("errorCode", "DUPLICATE");
				return result.toString();
			}
		}

		JsonObject result = new JsonObject();
		result.addProperty("isCanSave", true);
		return result.toString();
	}
	
	/**
	 * 获取所有节点的的运行状态
	 * @return 类型:String 返回节点的运行状态
	 */
	@RequestMapping(value = "/runningStatus", produces="application/json")
	public String runningStatus(){

		if(nodeMap == null || nodeMap.isEmpty()){	//如果缓存为空，将所有数据存入缓存
			List<ClusterNode> list = clusterNodeRepository.findAll();
			for (ClusterNode clusterNode : list) {
				nodeMap.put(clusterNode.getId(), clusterNode);
			}
		}
		
		JsonArray isRuning = new JsonArray();
		JsonArray isNotRuning = new JsonArray();
		
		for (ClusterNode clusterNode : nodeMap.values()) {
			String flag = RestAPI.requestByGetMethod(clusterNode.getIpaddr(), clusterNode.getPort()+"" ,"NODE");
			if(!StringUtils.equals(flag, "false")){
				isRuning.add(new JsonPrimitive(clusterNode.getId()));
			}else{
				isNotRuning.add(new JsonPrimitive(clusterNode.getId()));
			}
		}
		
		JsonObject resuslt = new JsonObject();
		resuslt.add("isRuning", isRuning);
		resuslt.add("isNotRuning", isNotRuning);
		return resuslt.toString();
	}
	
	@RequestMapping(value = "/runningInformations", produces = "application/json")
	public String runningInformations(String ipaddr, String port){
		//获取CPU信息
		String cpuJson = RestAPI.requestByGetMethod(ipaddr, port, "CPU");
		//如果节点死掉就获取不到相关信息
		if(StringUtils.equals(cpuJson, "false")){
			JsonObject result = new JsonObject();
			result.addProperty("node", false);	//节点判断标志false:挂掉，true:正常
			return result.toString();
		}
		double cpuInfo = RestAPI.getCPU(cpuJson);
		
		//获取空闲物理内存信息
		String freeMemoryJson = RestAPI.requestByGetMethod(ipaddr, port, "MEMORY");				
		double freeMemoryInfo = RestAPI.getMemory(freeMemoryJson);
		//获取空闲物理内存信息
		String totalMemoryJson = RestAPI.requestByGetMethod(ipaddr, port, "TOTALMEMORY");				
		double totalMemoryInfo = RestAPI.getMemory(totalMemoryJson);
		//获得使用的物理内存信息
		double memoryInfo = (totalMemoryInfo - freeMemoryInfo)/1024.0/1024.0;
		
		JsonObject result = new JsonObject();
		result.addProperty("node", true);
		result.addProperty("cpu", cpuInfo);
		result.addProperty("memory", memoryInfo);
		return result.toString();
	}
	
	/**
	 * 保存新增节点
	 * @param data
	 * @return
	 */
	@RequestMapping(value = "/save", produces = "application/json")
	public String saveNode(String data){
		Gson gson = new Gson();
		ClusterNode node = gson.fromJson(data, ClusterNode.class);
		clusterNodeRepository.save(node);
		nodeMap.put(node.getId(), node);
		
		JsonObject result = new JsonObject();
		result.addProperty("result", true);
		return result.toString();
	}
	
	/**
	 * 保存更新节点
	 * @param data
	 * @return
	 */
	@RequestMapping(value = "/update", produces = "application/json")
	public String updateNode(String data){
		Gson gson = new Gson();
		ClusterNode node = gson.fromJson(data, ClusterNode.class);
		ClusterNode temp = clusterNodeRepository.findById(node.getId());
		temp.setName(node.getName());
		temp.setIpaddr(node.getIpaddr());
		temp.setPort(node.getPort());
		temp.setRemark(node.getRemark());
		clusterNodeRepository.save(temp);
		nodeMap.put(temp.getId(), temp);
		
		JsonObject result = new JsonObject();
		result.addProperty("result", true);
		return result.toString();
	}
	
	/**
	 * 删除节点
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/delete", produces = "application/json")
	public String deleteNode(String id){
		ClusterNode node = clusterNodeRepository.findById(id);
		clusterNodeRepository.delete(node);
		nodeMap.remove(id);
		
		JsonObject result = new JsonObject();
		result.addProperty("result", true);
		return result.toString();
		
	}
	
	
	
}